home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / threading.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  26KB  |  886 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. """Thread module emulating a subset of Java's threading model."""
  5. import sys as _sys
  6.  
  7. try:
  8.     import thread
  9. except ImportError:
  10.     del _sys.modules[__name__]
  11.     raise 
  12.  
  13. from time import time as _time, sleep as _sleep
  14. from traceback import format_exc as _format_exc
  15. from collections import deque
  16. __all__ = [
  17.     'activeCount',
  18.     'Condition',
  19.     'currentThread',
  20.     'enumerate',
  21.     'Event',
  22.     'Lock',
  23.     'RLock',
  24.     'Semaphore',
  25.     'BoundedSemaphore',
  26.     'Thread',
  27.     'Timer',
  28.     'setprofile',
  29.     'settrace',
  30.     'local',
  31.     'stack_size']
  32. _start_new_thread = thread.start_new_thread
  33. _allocate_lock = thread.allocate_lock
  34. _get_ident = thread.get_ident
  35. ThreadError = thread.error
  36. del thread
  37. _VERBOSE = False
  38.  
  39. class _Verbose(object):
  40.     
  41.     def __init__(self, verbose = None):
  42.         if verbose is None:
  43.             verbose = _VERBOSE
  44.         
  45.         self._Verbose__verbose = verbose
  46.  
  47.     
  48.     def _note(self, format, *args):
  49.         if self._Verbose__verbose:
  50.             format = format % args
  51.             format = '%s: %s\n' % (currentThread().getName(), format)
  52.             _sys.stderr.write(format)
  53.         
  54.  
  55.  
  56. _profile_hook = None
  57. _trace_hook = None
  58.  
  59. def setprofile(func):
  60.     global _profile_hook
  61.     _profile_hook = func
  62.  
  63.  
  64. def settrace(func):
  65.     global _trace_hook
  66.     _trace_hook = func
  67.  
  68. Lock = _allocate_lock
  69.  
  70. def RLock(*args, **kwargs):
  71.     return _RLock(*args, **kwargs)
  72.  
  73.  
  74. class _RLock(_Verbose):
  75.     
  76.     def __init__(self, verbose = None):
  77.         _Verbose.__init__(self, verbose)
  78.         self._RLock__block = _allocate_lock()
  79.         self._RLock__owner = None
  80.         self._RLock__count = 0
  81.  
  82.     
  83.     def __repr__(self):
  84.         owner = self._RLock__owner
  85.         if owner:
  86.             pass
  87.         return '<%s(%s, %d)>' % (self.__class__.__name__, owner.getName(), self._RLock__count)
  88.  
  89.     
  90.     def acquire(self, blocking = 1):
  91.         me = currentThread()
  92.         if self._RLock__owner is me:
  93.             self._RLock__count = self._RLock__count + 1
  94.             self._note('%s.acquire(%s): recursive success', self, blocking)
  95.             return 1
  96.         
  97.         rc = self._RLock__block.acquire(blocking)
  98.         if rc:
  99.             self._RLock__owner = me
  100.             self._RLock__count = 1
  101.             self._note('%s.acquire(%s): initial success', self, blocking)
  102.         else:
  103.             self._note('%s.acquire(%s): failure', self, blocking)
  104.         return rc
  105.  
  106.     __enter__ = acquire
  107.     
  108.     def release(self):
  109.         if self._RLock__owner is not currentThread():
  110.             raise RuntimeError('cannot release un-aquired lock')
  111.         
  112.         self._RLock__count = count = self._RLock__count - 1
  113.         if not count:
  114.             self._RLock__owner = None
  115.             self._RLock__block.release()
  116.             self._note('%s.release(): final release', self)
  117.         else:
  118.             self._note('%s.release(): non-final release', self)
  119.  
  120.     
  121.     def __exit__(self, t, v, tb):
  122.         self.release()
  123.  
  124.     
  125.     def _acquire_restore(self, .1):
  126.         (count, owner) = .1
  127.         self._RLock__block.acquire()
  128.         self._RLock__count = count
  129.         self._RLock__owner = owner
  130.         self._note('%s._acquire_restore()', self)
  131.  
  132.     
  133.     def _release_save(self):
  134.         self._note('%s._release_save()', self)
  135.         count = self._RLock__count
  136.         self._RLock__count = 0
  137.         owner = self._RLock__owner
  138.         self._RLock__owner = None
  139.         self._RLock__block.release()
  140.         return (count, owner)
  141.  
  142.     
  143.     def _is_owned(self):
  144.         return self._RLock__owner is currentThread()
  145.  
  146.  
  147.  
  148. def Condition(*args, **kwargs):
  149.     return _Condition(*args, **kwargs)
  150.  
  151.  
  152. class _Condition(_Verbose):
  153.     
  154.     def __init__(self, lock = None, verbose = None):
  155.         _Verbose.__init__(self, verbose)
  156.         if lock is None:
  157.             lock = RLock()
  158.         
  159.         self._Condition__lock = lock
  160.         self.acquire = lock.acquire
  161.         self.release = lock.release
  162.         
  163.         try:
  164.             self._release_save = lock._release_save
  165.         except AttributeError:
  166.             pass
  167.  
  168.         
  169.         try:
  170.             self._acquire_restore = lock._acquire_restore
  171.         except AttributeError:
  172.             pass
  173.  
  174.         
  175.         try:
  176.             self._is_owned = lock._is_owned
  177.         except AttributeError:
  178.             pass
  179.  
  180.         self._Condition__waiters = []
  181.  
  182.     
  183.     def __enter__(self):
  184.         return self._Condition__lock.__enter__()
  185.  
  186.     
  187.     def __exit__(self, *args):
  188.         return self._Condition__lock.__exit__(*args)
  189.  
  190.     
  191.     def __repr__(self):
  192.         return '<Condition(%s, %d)>' % (self._Condition__lock, len(self._Condition__waiters))
  193.  
  194.     
  195.     def _release_save(self):
  196.         self._Condition__lock.release()
  197.  
  198.     
  199.     def _acquire_restore(self, x):
  200.         self._Condition__lock.acquire()
  201.  
  202.     
  203.     def _is_owned(self):
  204.         if self._Condition__lock.acquire(0):
  205.             self._Condition__lock.release()
  206.             return False
  207.         else:
  208.             return True
  209.  
  210.     
  211.     def wait(self, timeout = None):
  212.         if not self._is_owned():
  213.             raise RuntimeError('cannot wait on un-aquired lock')
  214.         
  215.         waiter = _allocate_lock()
  216.         waiter.acquire()
  217.         self._Condition__waiters.append(waiter)
  218.         saved_state = self._release_save()
  219.         
  220.         try:
  221.             if timeout is None:
  222.                 waiter.acquire()
  223.                 self._note('%s.wait(): got it', self)
  224.             else:
  225.                 endtime = _time() + timeout
  226.                 delay = 0.0005
  227.                 while True:
  228.                     gotit = waiter.acquire(0)
  229.                     if gotit:
  230.                         break
  231.                     
  232.                     remaining = endtime - _time()
  233.                     if remaining <= 0:
  234.                         break
  235.                     
  236.                     delay = min(delay * 2, remaining, 0.05)
  237.                     _sleep(delay)
  238.                 if not gotit:
  239.                     self._note('%s.wait(%s): timed out', self, timeout)
  240.                     
  241.                     try:
  242.                         self._Condition__waiters.remove(waiter)
  243.                     except ValueError:
  244.                         pass
  245.                     except:
  246.                         None<EXCEPTION MATCH>ValueError
  247.                     
  248.  
  249.                 None<EXCEPTION MATCH>ValueError
  250.                 self._note('%s.wait(%s): got it', self, timeout)
  251.         finally:
  252.             self._acquire_restore(saved_state)
  253.  
  254.  
  255.     
  256.     def notify(self, n = 1):
  257.         if not self._is_owned():
  258.             raise RuntimeError('cannot notify on un-aquired lock')
  259.         
  260.         _Condition__waiters = self._Condition__waiters
  261.         waiters = _Condition__waiters[:n]
  262.         if not waiters:
  263.             self._note('%s.notify(): no waiters', self)
  264.             return None
  265.         
  266.         if not n != 1 or 's':
  267.             pass
  268.         self._note('%s.notify(): notifying %d waiter%s', self, n, '')
  269.         for waiter in waiters:
  270.             waiter.release()
  271.             
  272.             try:
  273.                 _Condition__waiters.remove(waiter)
  274.             continue
  275.             except ValueError:
  276.                 continue
  277.             
  278.  
  279.         
  280.  
  281.     
  282.     def notifyAll(self):
  283.         self.notify(len(self._Condition__waiters))
  284.  
  285.  
  286.  
  287. def Semaphore(*args, **kwargs):
  288.     return _Semaphore(*args, **kwargs)
  289.  
  290.  
  291. class _Semaphore(_Verbose):
  292.     
  293.     def __init__(self, value = 1, verbose = None):
  294.         if value < 0:
  295.             raise ValueError('semaphore initial value must be >= 0')
  296.         
  297.         _Verbose.__init__(self, verbose)
  298.         self._Semaphore__cond = Condition(Lock())
  299.         self._Semaphore__value = value
  300.  
  301.     
  302.     def acquire(self, blocking = 1):
  303.         rc = False
  304.         self._Semaphore__cond.acquire()
  305.         while self._Semaphore__value == 0:
  306.             if not blocking:
  307.                 break
  308.             
  309.             self._note('%s.acquire(%s): blocked waiting, value=%s', self, blocking, self._Semaphore__value)
  310.             self._Semaphore__cond.wait()
  311.         self._Semaphore__value = self._Semaphore__value - 1
  312.         self._note('%s.acquire: success, value=%s', self, self._Semaphore__value)
  313.         rc = True
  314.         self._Semaphore__cond.release()
  315.         return rc
  316.  
  317.     __enter__ = acquire
  318.     
  319.     def release(self):
  320.         self._Semaphore__cond.acquire()
  321.         self._Semaphore__value = self._Semaphore__value + 1
  322.         self._note('%s.release: success, value=%s', self, self._Semaphore__value)
  323.         self._Semaphore__cond.notify()
  324.         self._Semaphore__cond.release()
  325.  
  326.     
  327.     def __exit__(self, t, v, tb):
  328.         self.release()
  329.  
  330.  
  331.  
  332. def BoundedSemaphore(*args, **kwargs):
  333.     return _BoundedSemaphore(*args, **kwargs)
  334.  
  335.  
  336. class _BoundedSemaphore(_Semaphore):
  337.     '''Semaphore that checks that # releases is <= # acquires'''
  338.     
  339.     def __init__(self, value = 1, verbose = None):
  340.         _Semaphore.__init__(self, value, verbose)
  341.         self._initial_value = value
  342.  
  343.     
  344.     def release(self):
  345.         if self._Semaphore__value >= self._initial_value:
  346.             raise ValueError, 'Semaphore released too many times'
  347.         
  348.         return _Semaphore.release(self)
  349.  
  350.  
  351.  
  352. def Event(*args, **kwargs):
  353.     return _Event(*args, **kwargs)
  354.  
  355.  
  356. class _Event(_Verbose):
  357.     
  358.     def __init__(self, verbose = None):
  359.         _Verbose.__init__(self, verbose)
  360.         self._Event__cond = Condition(Lock())
  361.         self._Event__flag = False
  362.  
  363.     
  364.     def isSet(self):
  365.         return self._Event__flag
  366.  
  367.     
  368.     def set(self):
  369.         self._Event__cond.acquire()
  370.         
  371.         try:
  372.             self._Event__flag = True
  373.             self._Event__cond.notifyAll()
  374.         finally:
  375.             self._Event__cond.release()
  376.  
  377.  
  378.     
  379.     def clear(self):
  380.         self._Event__cond.acquire()
  381.         
  382.         try:
  383.             self._Event__flag = False
  384.         finally:
  385.             self._Event__cond.release()
  386.  
  387.  
  388.     
  389.     def wait(self, timeout = None):
  390.         self._Event__cond.acquire()
  391.         
  392.         try:
  393.             if not self._Event__flag:
  394.                 self._Event__cond.wait(timeout)
  395.         finally:
  396.             self._Event__cond.release()
  397.  
  398.  
  399.  
  400. _counter = 0
  401.  
  402. def _newname(template = 'Thread-%d'):
  403.     global _counter
  404.     _counter = _counter + 1
  405.     return template % _counter
  406.  
  407. _active_limbo_lock = _allocate_lock()
  408. _active = { }
  409. _limbo = { }
  410.  
  411. class Thread(_Verbose):
  412.     __initialized = False
  413.     __exc_info = _sys.exc_info
  414.     
  415.     def __init__(self, group = None, target = None, name = None, args = (), kwargs = None, verbose = None):
  416.         if not group is None:
  417.             raise AssertionError, 'group argument must be None for now'
  418.         _Verbose.__init__(self, verbose)
  419.         if kwargs is None:
  420.             kwargs = { }
  421.         
  422.         self._Thread__target = target
  423.         if not name:
  424.             pass
  425.         self._Thread__name = str(_newname())
  426.         self._Thread__args = args
  427.         self._Thread__kwargs = kwargs
  428.         self._Thread__daemonic = self._set_daemon()
  429.         self._Thread__started = False
  430.         self._Thread__stopped = False
  431.         self._Thread__block = Condition(Lock())
  432.         self._Thread__initialized = True
  433.         self._Thread__stderr = _sys.stderr
  434.  
  435.     
  436.     def _set_daemon(self):
  437.         return currentThread().isDaemon()
  438.  
  439.     
  440.     def __repr__(self):
  441.         if not self._Thread__initialized:
  442.             raise AssertionError, 'Thread.__init__() was not called'
  443.         status = 'initial'
  444.         if self._Thread__started:
  445.             status = 'started'
  446.         
  447.         if self._Thread__stopped:
  448.             status = 'stopped'
  449.         
  450.         if self._Thread__daemonic:
  451.             status = status + ' daemon'
  452.         
  453.         return '<%s(%s, %s)>' % (self.__class__.__name__, self._Thread__name, status)
  454.  
  455.     
  456.     def start(self):
  457.         if not self._Thread__initialized:
  458.             raise RuntimeError('thread.__init__() not called')
  459.         
  460.         if self._Thread__started:
  461.             raise RuntimeError('thread already started')
  462.         
  463.         self._note('%s.start(): starting thread', self)
  464.         _active_limbo_lock.acquire()
  465.         _limbo[self] = self
  466.         _active_limbo_lock.release()
  467.         _start_new_thread(self._Thread__bootstrap, ())
  468.         self._Thread__started = True
  469.         _sleep(1e-06)
  470.  
  471.     
  472.     def run(self):
  473.         if self._Thread__target:
  474.             self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
  475.         
  476.  
  477.     
  478.     def __bootstrap(self):
  479.         
  480.         try:
  481.             self._Thread__bootstrap_inner()
  482.         except:
  483.             if self._Thread__daemonic and _sys is None:
  484.                 return None
  485.             
  486.             raise 
  487.  
  488.  
  489.     
  490.     def __bootstrap_inner(self):
  491.         
  492.         try:
  493.             self._Thread__started = True
  494.             _active_limbo_lock.acquire()
  495.             _active[_get_ident()] = self
  496.             del _limbo[self]
  497.             _active_limbo_lock.release()
  498.             self._note('%s.__bootstrap(): thread started', self)
  499.             if _trace_hook:
  500.                 self._note('%s.__bootstrap(): registering trace hook', self)
  501.                 _sys.settrace(_trace_hook)
  502.             
  503.             if _profile_hook:
  504.                 self._note('%s.__bootstrap(): registering profile hook', self)
  505.                 _sys.setprofile(_profile_hook)
  506.             
  507.             
  508.             try:
  509.                 self.run()
  510.             except SystemExit:
  511.                 self._note('%s.__bootstrap(): raised SystemExit', self)
  512.             except:
  513.                 self._note('%s.__bootstrap(): unhandled exception', self)
  514.                 if _sys:
  515.                     _sys.stderr.write('Exception in thread %s:\n%s\n' % (self.getName(), _format_exc()))
  516.                 else:
  517.                     (exc_type, exc_value, exc_tb) = self._Thread__exc_info()
  518.                     
  519.                     try:
  520.                         print >>self._Thread__stderr, 'Exception in thread ' + self.getName() + ' (most likely raised during interpreter shutdown):'
  521.                         print >>self._Thread__stderr, 'Traceback (most recent call last):'
  522.                         while exc_tb:
  523.                             print >>self._Thread__stderr, '  File "%s", line %s, in %s' % (exc_tb.tb_frame.f_code.co_filename, exc_tb.tb_lineno, exc_tb.tb_frame.f_code.co_name)
  524.                             exc_tb = exc_tb.tb_next
  525.                         print >>self._Thread__stderr, '%s: %s' % (exc_type, exc_value)
  526.                     finally:
  527.                         del exc_type
  528.                         del exc_value
  529.                         del exc_tb
  530.  
  531.  
  532.             self._note('%s.__bootstrap(): normal return', self)
  533.         finally:
  534.             _active_limbo_lock.acquire()
  535.             
  536.             try:
  537.                 self._Thread__stop()
  538.                 
  539.                 try:
  540.                     del _active[_get_ident()]
  541.                 except:
  542.                     pass
  543.  
  544.             finally:
  545.                 _active_limbo_lock.release()
  546.  
  547.  
  548.  
  549.     
  550.     def __stop(self):
  551.         self._Thread__block.acquire()
  552.         self._Thread__stopped = True
  553.         self._Thread__block.notifyAll()
  554.         self._Thread__block.release()
  555.  
  556.     
  557.     def __delete(self):
  558.         '''Remove current thread from the dict of currently running threads.'''
  559.         _active_limbo_lock.acquire()
  560.         
  561.         try:
  562.             del _active[_get_ident()]
  563.         except KeyError:
  564.             if 'dummy_threading' not in _sys.modules:
  565.                 raise 
  566.             
  567.         except:
  568.             'dummy_threading' not in _sys.modules
  569.         finally:
  570.             _active_limbo_lock.release()
  571.  
  572.  
  573.     
  574.     def join(self, timeout = None):
  575.         if not self._Thread__initialized:
  576.             raise RuntimeError('Thread.__init__() not called')
  577.         
  578.         if not self._Thread__started:
  579.             raise RuntimeError('cannot join thread before it is started')
  580.         
  581.         if self is currentThread():
  582.             raise RuntimeError('cannot join current thread')
  583.         
  584.         if not self._Thread__stopped:
  585.             self._note('%s.join(): waiting until thread stops', self)
  586.         
  587.         self._Thread__block.acquire()
  588.         
  589.         try:
  590.             if timeout is None:
  591.                 while not self._Thread__stopped:
  592.                     self._Thread__block.wait()
  593.                 self._note('%s.join(): thread stopped', self)
  594.             else:
  595.                 deadline = _time() + timeout
  596.                 while not self._Thread__stopped:
  597.                     delay = deadline - _time()
  598.                     if delay <= 0:
  599.                         self._note('%s.join(): timed out', self)
  600.                         break
  601.                     
  602.                     self._Thread__block.wait(delay)
  603.                 self._note('%s.join(): thread stopped', self)
  604.         finally:
  605.             self._Thread__block.release()
  606.  
  607.  
  608.     
  609.     def getName(self):
  610.         if not self._Thread__initialized:
  611.             raise AssertionError, 'Thread.__init__() not called'
  612.         return self._Thread__name
  613.  
  614.     
  615.     def setName(self, name):
  616.         if not self._Thread__initialized:
  617.             raise AssertionError, 'Thread.__init__() not called'
  618.         self._Thread__name = str(name)
  619.  
  620.     
  621.     def isAlive(self):
  622.         return None if not self._Thread__initialized else not (self._Thread__stopped)
  623.  
  624.     
  625.     def isDaemon(self):
  626.         if not self._Thread__initialized:
  627.             raise AssertionError, 'Thread.__init__() not called'
  628.         return self._Thread__daemonic
  629.  
  630.     
  631.     def setDaemon(self, daemonic):
  632.         if not self._Thread__initialized:
  633.             raise RuntimeError('Thread.__init__() not called')
  634.         
  635.         if self._Thread__started:
  636.             raise RuntimeError('cannot set daemon status of active thread')
  637.         
  638.         self._Thread__daemonic = daemonic
  639.  
  640.  
  641.  
  642. def Timer(*args, **kwargs):
  643.     return _Timer(*args, **kwargs)
  644.  
  645.  
  646. class _Timer(Thread):
  647.     """Call a function after a specified number of seconds:
  648.  
  649.     t = Timer(30.0, f, args=[], kwargs={})
  650.     t.start()
  651.     t.cancel() # stop the timer's action if it's still waiting
  652.     """
  653.     
  654.     def __init__(self, interval, function, args = [], kwargs = { }):
  655.         Thread.__init__(self)
  656.         self.interval = interval
  657.         self.function = function
  658.         self.args = args
  659.         self.kwargs = kwargs
  660.         self.finished = Event()
  661.  
  662.     
  663.     def cancel(self):
  664.         """Stop the timer if it hasn't finished yet"""
  665.         self.finished.set()
  666.  
  667.     
  668.     def run(self):
  669.         self.finished.wait(self.interval)
  670.         if not self.finished.isSet():
  671.             self.function(*self.args, **self.kwargs)
  672.         
  673.         self.finished.set()
  674.  
  675.  
  676.  
  677. class _MainThread(Thread):
  678.     
  679.     def __init__(self):
  680.         Thread.__init__(self, name = 'MainThread')
  681.         self._Thread__started = True
  682.         _active_limbo_lock.acquire()
  683.         _active[_get_ident()] = self
  684.         _active_limbo_lock.release()
  685.  
  686.     
  687.     def _set_daemon(self):
  688.         return False
  689.  
  690.     
  691.     def _exitfunc(self):
  692.         self._Thread__stop()
  693.         t = _pickSomeNonDaemonThread()
  694.         if t:
  695.             self._note('%s: waiting for other threads', self)
  696.         
  697.         while t:
  698.             t.join()
  699.             t = _pickSomeNonDaemonThread()
  700.         self._note('%s: exiting', self)
  701.         self._Thread__delete()
  702.  
  703.  
  704.  
  705. def _pickSomeNonDaemonThread():
  706.     for t in enumerate():
  707.         if not t.isDaemon() and t.isAlive():
  708.             return t
  709.             continue
  710.     
  711.  
  712.  
  713. class _DummyThread(Thread):
  714.     
  715.     def __init__(self):
  716.         Thread.__init__(self, name = _newname('Dummy-%d'))
  717.         del self._Thread__block
  718.         self._Thread__started = True
  719.         _active_limbo_lock.acquire()
  720.         _active[_get_ident()] = self
  721.         _active_limbo_lock.release()
  722.  
  723.     
  724.     def _set_daemon(self):
  725.         return True
  726.  
  727.     
  728.     def join(self, timeout = None):
  729.         if not False:
  730.             raise AssertionError, 'cannot join a dummy thread'
  731.  
  732.  
  733.  
  734. def currentThread():
  735.     
  736.     try:
  737.         return _active[_get_ident()]
  738.     except KeyError:
  739.         return _DummyThread()
  740.  
  741.  
  742.  
  743. def activeCount():
  744.     _active_limbo_lock.acquire()
  745.     count = len(_active) + len(_limbo)
  746.     _active_limbo_lock.release()
  747.     return count
  748.  
  749.  
  750. def enumerate():
  751.     _active_limbo_lock.acquire()
  752.     active = _active.values() + _limbo.values()
  753.     _active_limbo_lock.release()
  754.     return active
  755.  
  756. from thread import stack_size
  757. _shutdown = _MainThread()._exitfunc
  758.  
  759. try:
  760.     from thread import _local as local
  761. except ImportError:
  762.     from _threading_local import local
  763.  
  764.  
  765. def _after_fork():
  766.     global _active_limbo_lock
  767.     _active_limbo_lock = _allocate_lock()
  768.     new_active = { }
  769.     current = currentThread()
  770.     _active_limbo_lock.acquire()
  771.     
  772.     try:
  773.         for thread in _active.itervalues():
  774.             if thread is current:
  775.                 ident = _get_ident()
  776.                 thread._Thread__ident = ident
  777.                 new_active[ident] = thread
  778.                 continue
  779.             thread._Thread__stopped = True
  780.         
  781.         _limbo.clear()
  782.         _active.clear()
  783.         _active.update(new_active)
  784.         if not len(_active) == 1:
  785.             raise AssertionError
  786.     finally:
  787.         _active_limbo_lock.release()
  788.  
  789.  
  790.  
  791. def _test():
  792.     
  793.     class BoundedQueue(_Verbose):
  794.         
  795.         def __init__(self, limit):
  796.             _Verbose.__init__(self)
  797.             self.mon = RLock()
  798.             self.rc = Condition(self.mon)
  799.             self.wc = Condition(self.mon)
  800.             self.limit = limit
  801.             self.queue = deque()
  802.  
  803.         
  804.         def put(self, item):
  805.             self.mon.acquire()
  806.             while len(self.queue) >= self.limit:
  807.                 self._note('put(%s): queue full', item)
  808.                 self.wc.wait()
  809.             self.queue.append(item)
  810.             self._note('put(%s): appended, length now %d', item, len(self.queue))
  811.             self.rc.notify()
  812.             self.mon.release()
  813.  
  814.         
  815.         def get(self):
  816.             self.mon.acquire()
  817.             while not self.queue:
  818.                 self._note('get(): queue empty')
  819.                 self.rc.wait()
  820.             item = self.queue.popleft()
  821.             self._note('get(): got %s, %d left', item, len(self.queue))
  822.             self.wc.notify()
  823.             self.mon.release()
  824.             return item
  825.  
  826.  
  827.     
  828.     class ProducerThread(Thread):
  829.         
  830.         def __init__(self, queue, quota):
  831.             Thread.__init__(self, name = 'Producer')
  832.             self.queue = queue
  833.             self.quota = quota
  834.  
  835.         
  836.         def run(self):
  837.             random = random
  838.             import random
  839.             counter = 0
  840.             while counter < self.quota:
  841.                 counter = counter + 1
  842.                 self.queue.put('%s.%d' % (self.getName(), counter))
  843.                 _sleep(random() * 1e-05)
  844.  
  845.  
  846.     
  847.     class ConsumerThread(Thread):
  848.         
  849.         def __init__(self, queue, count):
  850.             Thread.__init__(self, name = 'Consumer')
  851.             self.queue = queue
  852.             self.count = count
  853.  
  854.         
  855.         def run(self):
  856.             while self.count > 0:
  857.                 item = self.queue.get()
  858.                 print item
  859.                 self.count = self.count - 1
  860.  
  861.  
  862.     NP = 3
  863.     QL = 4
  864.     NI = 5
  865.     Q = BoundedQueue(QL)
  866.     P = []
  867.     for i in range(NP):
  868.         t = ProducerThread(Q, NI)
  869.         t.setName('Producer-%d' % (i + 1))
  870.         P.append(t)
  871.     
  872.     C = ConsumerThread(Q, NI * NP)
  873.     for t in P:
  874.         t.start()
  875.         _sleep(1e-06)
  876.     
  877.     C.start()
  878.     for t in P:
  879.         t.join()
  880.     
  881.     C.join()
  882.  
  883. if __name__ == '__main__':
  884.     _test()
  885.  
  886.